#include "Object3DTranformation.h"


// Object3DTransformation methods



Object3DTransformation::Object3DTransformation(){

   
} 


Object3DTransformation::Object3DTransformation(long numRows,long numCols,double val):
                                        Matrix(numRows,numCols,val){

  // this->disp();
}


Object3DTransformation::Object3DTransformation(const char *fileName):Matrix(fileName){

   //transformedBy = new Matrix (fileName);
   //transformedBy(fileName);
   
  //   transformedBy->disp();
    // this->disp(); 
   cout<<"Object is taken from "<<fileName<<endl;
}


Object3DTransformation::Object3DTransformation(const Object3DTransformation & another){

       (*this) = another;
     
}



Object3DTransformation::~Object3DTransformation(){ 

}


//void Object3DTransformation :: setTransformedByMatrix(const Matrix &T){

       //transformedBy = new Matrix(T);
       //transformedBy->disp();
//}


Matrix Object3DTransformation::transform(const Matrix & T){

        
	transformedObject = new Matrix(numRows(), T.numCols(),1);
	      
        (*transformedObject) = (*this) * T; 
      
      //  transformedObject->disp();
      
            
      
      return (*transformedObject);               
}

Matrix Object3DTransformation :: transform(const double dx, const double dy,const double dz){

        Matrix T(4,4,0);
	
	T[0][0] = 1;
	T[1][1] = 1;
	T[2][2] = 1;
	T[3][3] = 1;
	
	T[3][0] = dx;
	T[3][1] = dy;
	T[3][2] = dz;
	
  
	transform(T);
	
     return (*transformedObject);        
}


Matrix Object3DTransformation::rotate(double angle, char rotationDirection){
   
        
       Matrix T(4,4);
       
       T = getRotationMatrix(angle ,rotationDirection);

       transformedObject = new Matrix(numRows(),T.numCols());
       
     (*transformedObject) = (*this) * T; 
      
     //transformedObject->disp();
      
    
  return (*transformedObject);
}

Matrix Object3DTransformation::scale(const Matrix & T){


    transformedObject = new Matrix(numRows(),T.numCols());
       
    
     (*transformedObject) = (*this) * T; 
      
     transformedObject->disp();
     //T.disp();

   return (*transformedObject);
}





Matrix Object3DTransformation::scale(const double dx , const double dy , const double dz){

    Matrix T(4,4,0);
    
    
    T[0][0] = dx;
    T[1][1] = dy;
    T[2][2] = dz;
    T[3][3] = 1;
    
    
    scale(T);
    //T.save("Scaling3DMatrix.txt");
           
    
  return (*transformedObject);
    
}


Matrix Object3DTransformation::sheare(const Matrix & A){

  transformedObject = new Matrix(numRows(),A.numCols());
       
     (*transformedObject) = (*this) * A; 
      
     //transformedObject->disp();
     
  return (*transformedObject);
}




Matrix Object3DTransformation::sheare(const double dx ,const double dy, const double dz){
   
    Matrix T(4,4,0);
    
    T[0][0] = 1;
    T[1][1] = 1;
    T[3][3] = 1;
    T[2][2] = 1;
    
    
    T[0][1] = dy;
    T[1][0] = dx;
    
  
    
    //T.save("ShearingMatrix.txt");
    
  sheare(T);    
  
  return (*transformedObject);
}



bool Object3DTransformation::save(const char *fileName){

       ofstream out(fileName);
	
	if(!out)
	{
	    cout <<"\n unable to open file : " <<fileName;
		return false;
	}
	
	out <<numRows() <<"   "  <<numCols() <<"\n\n";
	
	long i,j;
	for(i=0;i<numRows();i++)
	{
	    for(j=0;j<numCols();j++)
		{
		    out <<(*transformedObject)[i][j] <<"   ";
		}
		
		out <<"\n";
	}
	
	out <<"\n";
	
	return true;


}



Matrix Object3DTransformation::getTransformedObject(){

  return (*transformedObject);
}


Matrix Object3DTransformation::getRotationMatrix(double angle ,char rotationDirection){

    
   Matrix T(4,4,0);
    
    angle = (double) angle * (((double)22/7) / 180);
    
    
     if(rotationDirection == 'x'){
         
                T[0][0] = 1; 
		
		T[1][1] =abs(cos( abs(angle) ));
		T[1][2] =sin( abs(angle) );
		T[2][1] =sin(- abs(angle));
		T[2][2] =abs( cos( abs(angle) ));
		
		T[3][3] = 1;
    
     }else
     if(rotationDirection == 'y'){
      
                T[1][1] = 1; 
		
		T[0][0] =abs(cos( abs(angle) ));
		T[2][0] =sin( abs(angle) );
		T[0][2] =sin(- abs(angle));
		T[2][2] =abs( cos( abs(angle) ));
		
		T[3][3] = 1;
     
     
     }else
     if(rotationDirection == 'z'){
     
                T[2][2] = 1; 
		
		T[0][0] =abs(cos( abs(angle) ));
		T[0][1] =sin( abs(angle) );
		T[1][0] =sin(- abs(angle));
		T[1][1] =abs( cos( abs(angle) ));
		
		T[3][3] = 1;

     
     }
     //else return false;
     
          
          
         
   // T.save("Rotation3DMatrix.txt");
  
    return T; 
}
